package vip.xiaonuo.biz.modular.lancerGoodsBox.service.impl;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dromara.easyes.core.biz.EsPageInfo;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.ExistsQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.biz.modular.esmapping.BizGoodsBoxESMapper;
import vip.xiaonuo.biz.modular.lancerBrand.service.BizBrandService;
import vip.xiaonuo.biz.modular.lancerCategory.service.BizCategoryService;
import vip.xiaonuo.biz.modular.lancerCoupon.entity.BizCoupon;
import vip.xiaonuo.biz.modular.lancerCoupon.service.BizCouponService;
import vip.xiaonuo.biz.modular.lancerFile.FileService;
import vip.xiaonuo.biz.modular.lancerGoods.service.BizGoodsService;
import vip.xiaonuo.biz.modular.lancerUsercoupon.entity.BizUserCoupon;
import vip.xiaonuo.biz.modular.lancerUsercoupon.service.BizUserCouponService;
import vip.xiaonuo.biz.modular.pojo.domain.BizGoods;
import vip.xiaonuo.biz.modular.pojo.vo.LV;
import vip.xiaonuo.common.pojo.DbEnum;
import vip.xiaonuo.biz.modular.pojo.domain.BizGoodsBox;
import vip.xiaonuo.biz.modular.lancerGoodsBox.service.BizGoodsBoxService;
import vip.xiaonuo.biz.modular.mapper.BizGoodsBoxMapper;
import org.springframework.stereotype.Service;
import vip.xiaonuo.biz.modular.pojo.dto.add.GoodsBoxAddDTO;
import vip.xiaonuo.biz.modular.pojo.dto.common.CommonDeleteDTO;
import vip.xiaonuo.biz.modular.pojo.dto.common.CommonDetailDTO;
import vip.xiaonuo.biz.modular.pojo.dto.edit.GoodsBoxEditDTO;
import vip.xiaonuo.biz.modular.pojo.dto.page.ClientGoodsBoxPageDTO;
import vip.xiaonuo.biz.modular.pojo.dto.page.GoodsBoxPageDTO;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.dev.modular.file.provider.DevFileApiProvider;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * @author LancerAdmin
 * @description 针对表【biz_goods_box(商品盒子表)】的数据库操作Service实现
 * @createDate 2024-02-29 14:54:24
 */
@Service
public class BizGoodsBoxServiceImpl extends ServiceImpl<BizGoodsBoxMapper, BizGoodsBox>
        implements BizGoodsBoxService {
    @Resource
    private DevFileApiProvider devFileApi;


    @Override
    public Page<BizGoodsBox> pageBus(GoodsBoxPageDTO dto) {
        // 获取brand_id，其实就是create_user
        SaBaseLoginUser loginUser = StpLoginUserUtil.getLoginUser();
        String userId = loginUser.getId();
        LambdaQueryWrapper<BizGoodsBox> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(BizGoodsBox::getBrandId, userId)
                .like(ObjectUtil.isNotEmpty(dto.getGoodsBoxDetail()),
                        BizGoodsBox::getGoodsBoxDetail,
                        dto.getGoodsBoxDetail())
                .like(ObjectUtil.isNotEmpty(dto.getGoodsBoxName()),
                        BizGoodsBox::getGoodsBoxName,
                        dto.getGoodsBoxName())
                .like(ObjectUtil.isNotEmpty(dto.getBrandName()),
                        BizGoodsBox::getBrandName,
                        dto.getBrandName())
                .orderByDesc(BizGoodsBox::getCreateTime);

        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Override
    public BizGoodsBox detail(CommonDetailDTO dto) {
        return this.getById(dto.getId());
    }

    @Autowired
    FileService fileService;
    @Autowired
    BizBrandService brandService;


    @Override
    public void add(GoodsBoxAddDTO dto) {
        // 获取品牌名称
        String brandNameByUserId = brandService.getBrandNameByUserId();
        BizGoodsBox obj = new BizGoodsBox();
        // 文件上传
        // 上传到minio
        String minioWordUrl = devFileApi.storageFileWithReturnUrlMinio(dto.getGoodsBoxImgUrl());
        obj.setGoodsBoxImgUrl(minioWordUrl);
        obj
                .setGoodsBoxName(dto.getGoodsBoxName())
                .setCategoryId(dto.getCategoryId())
                .setBrandId(StpLoginUserUtil.getLoginUser().getId())
                .setBrandName(brandNameByUserId)
                .setGoodsBoxDetail(dto.getGoodsBoxDetail())
                .setGoodsBoxPriceFee(dto.getGoodsBoxPriceFee())
                .setGoodsBoxImgUrl(minioWordUrl)
                .setCurrEnergy(0);
        this.save(obj);


    }

    @Override
    @Transactional
    public void delete(List<CommonDeleteDTO> dto) {
        List<String> idList = CollStreamUtil.toList(dto, CommonDeleteDTO::getId);
        // 删除类型
        this.removeBatchByIds(idList);
        // 删除盒子内的商品

    }

    @Override
    public void edit(GoodsBoxEditDTO dto) {
        if (ObjectUtil.isEmpty(this.getById(dto.getId()))) {
            throw new CommonException("当前商品盒子id不存在！");
        }
        String isChangeImg = dto.getIsChangeImg();
        DbEnum.YOrN.validate(isChangeImg);
        BizGoodsBox obj = new BizGoodsBox();
        obj.setId(dto.getId())
                .setGoodsBoxName(dto.getGoodsBoxName())
                .setCategoryId(dto.getCategoryId())
                .setGoodsBoxDetail(dto.getGoodsBoxDetail())
                .setGoodsBoxPriceFee(dto.getGoodsBoxPriceFee());
        // 是否上传新的头像
        if (DbEnum.YOrN.YES.getValue().equals(isChangeImg)) {
            // 上传到minio
            String minioWordUrl = devFileApi.storageFileWithReturnUrlMinio(dto.getGoodsBoxImgUrl());
            obj.setGoodsBoxImgUrl(minioWordUrl);
        }
        this.updateById(obj);

    }

    @Override
    public Page<BizGoodsBox> pageLAdmin(GoodsBoxPageDTO dto) {
        LambdaQueryWrapper<BizGoodsBox> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .like(ObjectUtil.isNotEmpty(dto.getGoodsBoxDetail()),
                        BizGoodsBox::getGoodsBoxDetail,
                        dto.getGoodsBoxDetail())
                .like(ObjectUtil.isNotEmpty(dto.getGoodsBoxName()),
                        BizGoodsBox::getGoodsBoxName,
                        dto.getGoodsBoxName())
                .like(ObjectUtil.isNotEmpty(dto.getBrandName()),
                        BizGoodsBox::getBrandName,
                        dto.getBrandName())
                .orderByDesc(BizGoodsBox::getCreateTime);

        return this.page(CommonPageRequest.defaultPage(), queryWrapper);

    }

    @Override
    public BizGoodsBox getObjById(String id) {
        return this.getById(id);
    }

    @Autowired
    BizGoodsService goodsService;

    @Override
    public BizGoodsBox getObjByGoodsId(String goodsId) {
        String boxId = goodsService.getById(goodsId).getGoodsBoxId();
        return getObjById(boxId);
    }


    @Autowired
    BizGoodsBoxESMapper boxESMapper;

    @Override
    public EsPageInfo<BizGoodsBox> TreasureOfZhendianByES(ClientGoodsBoxPageDTO dto){
        String search = dto.getSearch();
        // 查询
        LambdaEsQueryWrapper<BizGoodsBox> esQueryWrapper=new LambdaEsQueryWrapper<>();
        esQueryWrapper.gt(BizGoodsBox::getCurrEnergy, 0)
                .match(ObjectUtil.isNotEmpty(search),BizGoodsBox::getGoodsBoxName,search);
        return boxESMapper.pageQuery(esQueryWrapper, 1, 100);
    }
    @Override
    public Page<BizGoodsBox> TreasureOfZhendian(ClientGoodsBoxPageDTO dto) {
        String search = dto.getSearch();
        LambdaQueryWrapper<BizGoodsBox> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .ge(BizGoodsBox::getCurrEnergy, 1)
                .like(ObjectUtil.isNotEmpty(search),
                        BizGoodsBox::getGoodsBoxDetail,
                        search);
        Page<BizGoodsBox> page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
        if (page.getTotal() < 1) {
            LambdaQueryWrapper<BizGoodsBox> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2
                    .ge(BizGoodsBox::getCurrEnergy, 1)

                    .like(ObjectUtil.isNotEmpty(search),
                            BizGoodsBox::getBrandName,
                            search);
            page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
        }
        return page;
    }

    @Autowired
    BizCategoryService categoryService;

    @Override
    public Page<BizGoodsBox> NewGoods(ClientGoodsBoxPageDTO dto) {
        String search = dto.getSearch();
        List<String> idListByParentId = categoryService.getIdListByParentId(dto.getParentId());
        if (ObjectUtil.isEmpty(idListByParentId)) {
            throw new CommonException("当前标签下没有商品");
        }
        LambdaQueryWrapper<BizGoodsBox> queryWrapper = new LambdaQueryWrapper<>();
        // 引入ES查询
        queryWrapper
                .ge(BizGoodsBox::getCurrEnergy, 1)

                .like(ObjectUtil.isNotEmpty(search),
                        BizGoodsBox::getGoodsBoxDetail,
                        search)
                .in(BizGoodsBox::getCategoryId, idListByParentId);
        Page<BizGoodsBox> page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
        if (page.getTotal() < 1) {
            LambdaQueryWrapper<BizGoodsBox> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2
                    .ge(BizGoodsBox::getCurrEnergy, 1)

                    .like(ObjectUtil.isNotEmpty(search),
                            BizGoodsBox::getBrandName,
                            search)
                    .in(BizGoodsBox::getCategoryId, idListByParentId);

            page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
        }
        return page;
    }

    @Override
    public Page<BizGoodsBox> GoodsKill(ClientGoodsBoxPageDTO dto) {
        return null;
    }

    @Override
    public List<BizGoodsBox> allGoodsBox() {
        // 获取当前的品牌
        SaBaseLoginUser loginUser = StpLoginUserUtil.getLoginUser();
        List<String> roleCodeList = loginUser.getRoleCodeList();

        LambdaQueryWrapper<BizGoodsBox> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(BizGoodsBox::getId, BizGoodsBox::getGoodsBoxName);
        // 管理员全部都能看
        if (roleCodeList.contains("superAdmin") || roleCodeList.contains("bizAdmin")) {
            return this.list(queryWrapper);
        }
        // 品牌方只能看自己的
        else if (roleCodeList.contains("brandUser")) {
            queryWrapper.eq(BizGoodsBox::getBrandId, loginUser.getId());
            return this.list(queryWrapper);
        }
        // 其他不允许看
        else {
            return new ArrayList<>();
        }
    }

    @Override
    public List<BizGoodsBox> allGoodsBoxByBrandId(String id) {
        return getListByBrandId(id);
    }

    @Override
    public List<BizGoodsBox> getListByBrandId(String BrandId) {
        LambdaQueryWrapper<BizGoodsBox> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BizGoodsBox::getBrandId, BrandId);
        return this.list(queryWrapper);
    }

    @Override
    public void incEnergy(String goodsBoxId) {
        if (ObjectUtil.isNotEmpty(goodsBoxId)) {
            this.getBaseMapper().incEnergy(goodsBoxId);

        }
    }

    @Override
    public void redEnergy(String goodsBoxId) {
        if (ObjectUtil.isNotEmpty(goodsBoxId)) {
            this.getBaseMapper().redEnergy(goodsBoxId);
        }
    }

    @Override
    public Page<BizGoodsBox> pageClient(GoodsBoxPageDTO dto) {
        String searchVal = dto.getSearchVal();
        // 引入ES搜索

        return null;
    }

    @Autowired
    BizCouponService couponService;
    @Autowired
    BizUserCouponService userCouponService;

    @Override
    public List<BizCoupon> getCouponListByBoxId(String boxId) {
        // 优惠券
        String userId = StpLoginUserUtil.getLoginUser().getId();
        // 获取当前用户的所有优惠券
        List<BizUserCoupon> userCouponList = userCouponService.getUserCouponListByUserId(userId);
        if (ObjectUtil.isEmpty(userCouponList)) {
            return new ArrayList<>();
        }
        // 查询当前盒子用户有没有领取优惠券
        List<String> couponIdList = userCouponList.stream().map(BizUserCoupon::getCouponId).collect(Collectors.toList());
        LambdaQueryWrapper<BizCoupon> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(BizCoupon::getId, couponIdList)
                .eq(BizCoupon::getGoodsBoxId, boxId);
        return couponService.list(queryWrapper);
    }

    @Override
    public List<LV> handleSearch(String searchVal) {
        List<LV> lvs = new ArrayList<>();
        SearchRequest searchRequest = new SearchRequest(DbEnum.ESIndex);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.suggest(new SuggestBuilder().addSuggestion(
                "mySuggestion", SuggestBuilders.completionSuggestion("suggestions")
                        .prefix(searchVal)
                        .skipDuplicates(true)
                        .size(20)
        ));
        searchRequest.source(builder);
        try {
            SearchResponse response = boxESMapper.search(searchRequest, RequestOptions.DEFAULT);
           CompletionSuggestion mySuggestion = response.getSuggest().getSuggestion("mySuggestion");
            List<CompletionSuggestion.Entry.Option> list = mySuggestion.getOptions();
            for (CompletionSuggestion.Entry.Option option : list) {
                String string = option.getText().toString();
                LV lv = new LV();
                lv.setLabel(string);
                lv.setValue(string);
                lvs.add(lv);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 判断有没有当前的值
        long count = lvs.stream().map(LV::getValue).filter(x -> x.equals(searchVal)).count();
        if (count<1){
            LV lv = new LV();
            lv.setLabel(searchVal);
            lv.setValue(searchVal);
            lvs.add(lv);
            Collections.reverse(lvs);
        }
        return lvs;
    }

    @Override
    public List<BizGoods> currBoxGoods(String goodsBoxId) {
        LambdaQueryWrapper<BizGoods> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(BizGoods::getGoodsBoxId,goodsBoxId);
        return goodsService.list(queryWrapper);
    }

}